feat(scouts): add cross-fleet scout findings page#3037
Conversation
Port the cloud Inbox's scouts-modal FindingsPanel into the Code app as a new page at /code/agents/scouts/findings, reached via a callout in the Scouts section under Agents. It lists every finding the troop emitted recently in one place, newest-first, searchable and filterable by scout/severity with a sort toggle (newest/oldest/severity/confidence). Each card shows the emitting scout and a chip into the inbox report its signal grouped into. Reuses the existing scout data plumbing (useScoutRuns/useScoutRunEmissions/ useScoutEmissionReports, ScoutEmissionCard); the runs query is cache-shared with the fleet section so opening the page does not double-fetch. Pure join/filter/sort logic lives in core (scoutFindings.ts) with unit tests.
|
React Doctor found no issues in the changed files. 🎉 Reviewed by React Doctor for commit |
Place the Scout findings callout inside the expanded scout fleet section, just above the scratchpad (FleetMemoryCallout) callout, instead of below the fleet in the outer Agents section. Match its styling to the adjacent scratchpad callout.
|
Reviews (1): Last reviewed commit: "fix(scouts): move findings callout into ..." | Re-trigger Greptile |
- Stale-data warning also fires on a background runs-refetch failure (runsError), not just emissions errors. - Drop superfluous .slice() before .sort() in mostRecentEmittedRuns and filterAndSortScoutFindings (.filter() already returns a fresh array). - Parameterise the sort tests with it.each and add 'oldest' coverage.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 790013afbf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| import { ScoutFindingsView } from "@posthog/ui/features/scouts/components/ScoutFindingsView"; | ||
| import { createFileRoute } from "@tanstack/react-router"; | ||
|
|
||
| export const Route = createFileRoute("/code/agents/scouts/findings")({ |
There was a problem hiding this comment.
Avoid shadowing the findings scout slug
When a project has a custom scout named signals-scout-findings, scoutSkillSlug strips the prefix to findings, and the existing row links build /code/agents/scouts/$skillName with that value (ScoutRowCard.tsx:72-73, scout-naming.ts:4-7). This new static route uses the same URL, so those rows/deep links route to the fleet findings page instead of the scout detail; put the fleet page under a non-conflicting segment or reserve/handle this slug explicitly.
Useful? React with 👍 / 👎.
| {hasLoadedOnce && | ||
| emissionsError && | ||
| emissionsFetching === false && |
There was a problem hiding this comment.
Surface stale rows when the runs refresh fails
When the page has already loaded and the runs-window poll fails (useScoutRuns.ts:24-26 refetches every 60s), React Query retains previous data, so rows.length > 0 and loadFailed is true but this warning is skipped because it only checks emissionsError. Users then see stale/incomplete cross-fleet findings with no error banner; include runsError/loadFailed in this stale-data warning.
Useful? React with 👍 / 👎.
| {isFiltering | ||
| ? "No findings match your search and filters." | ||
| : "Your scouts haven't emitted any findings yet. As they scan your project, what they surface shows up here."} |
There was a problem hiding this comment.
Don't report missing emission details as no findings
If the runs window contains emitted runs but batchScoutRunEmissions returns no detail rows for them (the existing per-scout view explicitly handles this at ScoutSignalsSection.tsx:160-162), this page falls through to the “haven't emitted any findings yet” empty state because it only checks rows.length. That misrepresents projects where findings were emitted but details are unavailable/deleted; compare against the run-level emitted_count and show an unavailable/incomplete state instead.
Useful? React with 👍 / 👎.
What
Adds a Scout findings page to the Code app at
/code/agents/scouts/findings, reached via a callout in the Scouts section under Agents. It ports the cloud Inbox's scouts-modalFindingsPanel(frontend/src/scenes/inbox/components/findings/FindingsPanel.tsx) so the desktop surface stays in parity.A cross-fleet findings browser — every finding the troop emitted recently in one place:
How
Reuses the existing scout data plumbing (
useScoutRuns,useScoutRunEmissions,useScoutEmissionReports,ScoutEmissionCard). The runs query is cache-shared with the fleet section, so opening the page doesn't double-fetch the window. Pure join/filter/sort/summarize logic lives in@posthog/core(scoutFindings.ts) behind unit tests; the UI hook only wires queries.New
packages/core/src/scouts/scoutFindings.ts— emitted-run capping, row join, filter/sort, summariespackages/core/src/scouts/scoutFindings.test.ts— 15 testspackages/ui/src/features/scouts/hooks/useScoutFindings.tspackages/ui/src/features/scouts/components/ScoutFindingsView.tsxpackages/ui/src/features/scouts/components/FleetFindingsCallout.tsxpackages/ui/src/router/routes/code/agents/scouts.findings.tsxChanged
ScoutEmissionCard.tsx— optionalscoutLabelto show the emitting scout on cross-fleet cardsnavigationBridge.ts—navigateToScoutFindings()ConfigureAgentsSection.tsx— wired the callout under the fleetanalytics-events.ts—scout_findingssurface +open_findings/filter_findings/sort_findingsactionsrouteTree.gen.ts— regeneratedTesting
noRestrictedImports)Note: the UI package has pre-existing typecheck errors in
sessions/components/chat-thread/session-updatefrom a stale@posthog/quillinstall (just-merged ChatX feature) — unrelated to this PR; none are in changed files.